{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<!--NAVIGATION-->\n",
    "< [在数组上计算：广播](02.05-Computation-on-arrays-broadcasting.ipynb) | [目录](Index.ipynb) | [高级索引](02.07-Fancy-Indexing.ipynb) >\n",
    "\n",
    "<a href=\"https://colab.research.google.com/github/wangyingsm/Python-Data-Science-Handbook/blob/master/notebooks/02.06-Boolean-Arrays-and-Masks.ipynb\"><img align=\"left\" src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open in Colab\" title=\"Open and Execute in Google Colaboratory\"></a>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Comparisons, Masks, and Boolean Logic\n",
    "\n",
    "# 比较，遮盖和布尔逻辑"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> This section covers the use of Boolean masks to examine and manipulate values within NumPy arrays.\n",
    "Masking comes up when you want to extract, modify, count, or otherwise manipulate values in an array based on some criterion: for example, you might wish to count all values greater than a certain value, or perhaps remove all outliers that are above some threshold.\n",
    "In NumPy, Boolean masking is often the most efficient way to accomplish these types of tasks.\n",
    "\n",
    "本小节将介绍使用布尔遮盖（掩码）来测试和操作NumPy数组的知识。当我们想通过一些标准对数组中的元素值进行提取、修改、计数或者其他一些操作的时候，我们需要使用遮盖：例如，你需要计算所有大于某个特定值的元素个数，或者删除那些超出阈值的离群值。在NumPy当中，布尔遮盖基本上是实现这类任务的最有效方式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example: Counting Rainy Days\n",
    "\n",
    "## 例子：计算下雨的天数\n",
    "\n",
    "> Imagine you have a series of data that represents the amount of precipitation each day for a year in a given city.\n",
    "For example, here we'll load the daily rainfall statistics for the city of Seattle in 2014, using Pandas (which is covered in more detail in [Chapter 3](03.00-Introduction-to-Pandas.ipynb)):\n",
    "\n",
    "设想你有一系列数据代表着某个城市一年中每天的降水量。例如，下面我们将使用Pandas读取2014年西雅图的每天降雨统计数据（Pandas我们将在[第三章](03.00-Introduction-to-Pandas.ipynb)详细介绍）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(365,)"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "# 使用Pandas读取降水量以英寸为单位的数据\n",
    "rainfall = pd.read_csv('data/Seattle2014.csv')['PRCP'].values\n",
    "inches = rainfall / 254.0  # 0.1毫米转换成英寸\n",
    "inches.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The array contains 365 values, giving daily rainfall in inches from January 1 to December 31, 2014.\n",
    "\n",
    "这个数组包含着365个元素值，这些值代表着西雅图市2014年从1月1日到12月31日的降雨（单位英寸）。\n",
    "\n",
    "> As a first quick visualization, let's look at the histogram of rainy days, which was generated using Matplotlib (we will explore this tool more fully in [Chapter 4](04.00-Introduction-To-Matplotlib.ipynb)):\n",
    "\n",
    "我们使用图表可视化展示一下，用简单的直方图来画出降雨天数的分布情况。这里需要使用到Matplotlib（有关内容我们将在[第四章](04.00-Introduction-To-Matplotlib.ipynb)详细介绍）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn; seaborn.set()  # 设置图表的风格，seaborn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist(inches, 40); # 将降水量区间40等分作为横轴，将落在区间的元素个数作为纵轴"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> This histogram gives us a general idea of what the data looks like: despite its reputation, the vast majority of days in Seattle saw near zero measured rainfall in 2014.\n",
    "But this doesn't do a good job of conveying some information we'd like to see: for example, how many rainy days were there in the year? What is the average precipitation on those rainy days? How many days were there with more than half an inch of rain?\n",
    "\n",
    "上面的直方图给我们提供了一个对这个数据集的通用观察结论：虽然名声在外，但事实上西雅图在2014年中绝大部分日子的降雨量都接近于0。但是这张图并没有帮助我们了解一些我们希望得到的数据：例如，一年之中有多少天在下雨？下雨的日子中降水量的平均值是多少？一年之中有多少天降水量超过半英寸？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Digging into the data\n",
    "\n",
    "### 挖掘数据\n",
    "\n",
    "> One approach to this would be to answer these questions by hand: loop through the data, incrementing a counter each time we see values in some desired range.\n",
    "For reasons discussed throughout this chapter, such an approach is very inefficient, both from the standpoint of time writing code and time computing the result.\n",
    "We saw in [Computation on NumPy Arrays: Universal Functions](02.03-Computation-on-arrays-ufuncs.ipynb) that NumPy's ufuncs can be used in place of loops to do fast element-wise arithmetic operations on arrays; in the same way, we can use other ufuncs to do element-wise *comparisons* over arrays, and we can then manipulate the results to answer the questions we have.\n",
    "We'll leave the data aside for right now, and discuss some general tools in NumPy to use *masking* to quickly answer these types of questions.\n",
    "\n",
    "有一种方法我们已经掌握了：循环遍历数据，然后对每个元素的值进行判断是否处在相应的范围。在前面的小节中，我们已经解释了为什么这种方式是低效的原因，无论从写代码花的时间来看还是从计算结果需要的时间来看。在[使用Numpy计算：通用函数](02.03-Computation-on-arrays-ufuncs.ipynb)小节中，我们学习了NumPy的ufuncs可以用来替代循环进行逐个元素的算术计算；同样的，我们也可以使用其他的ufuncs来对每个元素进行*比较*运算，通过这种方法我们就可以很简单的回答上面问题。我们暂且放下例子的数据，先介绍一些NumPy中用来进行*遮盖*的通用工具，适合这种任务的处理。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comparison Operators as ufuncs\n",
    "\n",
    "## UFuncs的比较运算符\n",
    "\n",
    "> In [Computation on NumPy Arrays: Universal Functions](02.03-Computation-on-arrays-ufuncs.ipynb) we introduced ufuncs, and focused in particular on arithmetic operators. We saw that using ``+``, ``-``, ``*``, ``/``, and others on arrays leads to element-wise operations.\n",
    "NumPy also implements comparison operators such as ``<`` (less than) and ``>`` (greater than) as element-wise ufuncs.\n",
    "The result of these comparison operators is always an array with a Boolean data type.\n",
    "All six of the standard comparison operations are available:\n",
    "\n",
    "在[使用Numpy计算：通用函数](02.03-Computation-on-arrays-ufuncs.ipynb)小节中，我们介绍了ufuncs，而且主要集中介绍了算术运算符。我们知道可以使用`+`、`-`、`*`、`/`和其他的运算可以对数组进行逐个元素的运算操作。NumPy同样也实现了比较运算符如`<`（小于）和`>`（大于）的ufuncs。这些比较运算符的结算结果一定是一个布尔类型的数组。全部6种标准的比较运算都是支持的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.array([1, 2, 3, 4, 5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True,  True, False, False, False])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x < 3  # less than"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False,  True,  True])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x > 3  # greater than"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True,  True,  True, False, False])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x <= 3  # less than or equal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False,  True,  True,  True])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x >= 3  # greater than or equal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True,  True, False,  True,  True])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x != 3  # not equal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False,  True, False, False])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x == 3  # equal"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> It is also possible to do an element-wise comparison of two arrays, and to include compound expressions:\n",
    "\n",
    "也可以对两个数组的每个元素进行比较，还支持运算的组合操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False,  True, False, False, False])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(2 * x) == (x ** 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> As in the case of arithmetic operators, the comparison operators are implemented as ufuncs in NumPy; for example, when you write ``x < 3``, internally NumPy uses ``np.less(x, 3)``.\n",
    "    A summary of the comparison operators and their equivalent ufunc is shown here:\n",
    "\n",
    "就像算术运算符一样，比较运算符实际上也是NumPy的ufuncs的简写方式；例如，当你写`x < 3`的时候，实际上调用的是NumPy的`np.less(x, 3)`。小标列出了比较运算符及其对应的ufuncs：\n",
    "\n",
    "| 运算符\t    | 相应的ufunc    || 运算符\t   | 相应的ufunc    |\n",
    "|---------------|---------------------||---------------|---------------------|\n",
    "|``==``         |``np.equal``         ||``!=``         |``np.not_equal``     |\n",
    "|``<``          |``np.less``          ||``<=``         |``np.less_equal``    |\n",
    "|``>``          |``np.greater``       ||``>=``         |``np.greater_equal`` |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Just as in the case of arithmetic ufuncs, these will work on arrays of any size and shape.\n",
    "Here is a two-dimensional example:\n",
    "\n",
    "如同算术运算ufuncs，比较运算也能应用在任何长度任何形状的数组上。下面是一个二维数组例子："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5, 0, 3, 3],\n",
       "       [7, 9, 3, 5],\n",
       "       [2, 4, 7, 6]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rng = np.random.RandomState(0)\n",
    "x = rng.randint(10, size=(3, 4))\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ True,  True,  True,  True],\n",
       "       [False, False,  True,  True],\n",
       "       [ True,  True, False, False]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x < 6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> In each case, the result is a Boolean array, and NumPy provides a number of straightforward patterns for working with these Boolean results.\n",
    "\n",
    "在任何的情况下，结果都是一个布尔类型数组，NumPy还提供了数量众多的函数能够直接对这些布尔数组进行操作。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Working with Boolean Arrays\n",
    "\n",
    "## 操作布尔数组\n",
    "\n",
    "> Given a Boolean array, there are a host of useful operations you can do.\n",
    "We'll work with ``x``, the two-dimensional array we created earlier.\n",
    "\n",
    "对于一个布尔数组，你可以进行许多有用的操作。我们继续使用上面我们创建的二维数组`x`来说明。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[5 0 3 3]\n",
      " [7 9 3 5]\n",
      " [2 4 7 6]]\n"
     ]
    }
   ],
   "source": [
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Counting entries\n",
    "\n",
    "### 计算元素个数\n",
    "\n",
    "> To count the number of ``True`` entries in a Boolean array, ``np.count_nonzero`` is useful:\n",
    "\n",
    "要计算一个布尔数组的真值`True`元素的个数，`np.count_nonzero`可以做到："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 有多少个元素小于6？\n",
    "np.count_nonzero(x < 6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> We see that there are eight array entries that are less than 6.\n",
    "Another way to get at this information is to use ``np.sum``; in this case, ``False`` is interpreted as ``0``, and ``True`` is interpreted as ``1``:\n",
    "\n",
    "我们可以看到数组当中有8个元素的值小于6.另一种可选的方法是使用`np.sum`；因为在Python中，`False`实际上代表0，而`True`实际上代表1："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sum(x < 6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The benefit of ``sum()`` is that like with other NumPy aggregation functions, this summation can be done along rows or columns as well:\n",
    "\n",
    "使用`sum()`函数的好处是它的使用就像NumPy的聚合函数一样，可以沿着不同的维度进行计算（如行或列）："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4, 2, 2])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在每一行中有多少个元素小于6？\n",
    "np.sum(x < 6, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> This counts the number of values less than 6 in each row of the matrix.\n",
    "\n",
    "上例计算了矩阵中每一行中小于6的元素的个数。\n",
    "\n",
    "> If we're interested in quickly checking whether any or all the values are true, we can use (you guessed it) ``np.any`` or ``np.all``:\n",
    "\n",
    "如果我们关心的问题是，是否有任何的元素值或全部的元素值为True，我们可以使用`np.any`或`np.all`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 有没有任何一个元素大于8？\n",
    "np.any(x > 8)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 有没有任何元素小于0\n",
    "np.any(x < 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 所有的元素都小于10？\n",
    "np.all(x < 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 所有的元素都等于6？\n",
    "np.all(x == 6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> ``np.all`` and ``np.any`` can be used along particular axes as well. For example:\n",
    "\n",
    "`np.all`和`np.any`也可以沿着特定的轴进行运算，例如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True, False,  True])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 是否每一行的所有值都小于8？\n",
    "np.all(x < 8, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Here all the elements in the first and third rows are less than 8, while this is not the case for the second row.\n",
    "\n",
    "上例结果表明，第一行和第三行所有的元素值都小于8，而第二行却不满足。\n",
    "\n",
    "> Finally, a quick warning: as mentioned in [Aggregations: Min, Max, and Everything In Between](02.04-Computation-on-arrays-aggregates.ipynb), Python has built-in ``sum()``, ``any()``, and ``all()`` functions. These have a different syntax than the NumPy versions, and in particular will fail or produce unintended results when used on multidimensional arrays. Be sure that you are using ``np.sum()``, ``np.any()``, and ``np.all()`` for these examples!\n",
    "\n",
    "最后提醒一下：就像在[聚合：Min, Max, 以及其他](02.04-Computation-on-arrays-aggregates.ipynb)中提示过的一样，Python也有內建的`sum()`、`any()`和`all()`函数。它们和NumPy对应的函数有着不同的语法，特别是应用在多维数组进行计算时，会得到错误和无法预料的结果。你需要保证使用NumPy提供的函数来进行相应的运算。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Boolean operators\n",
    "\n",
    "### 布尔运算符\n",
    "\n",
    "> We've already seen how we might count, say, all days with rain less than four inches, or all days with rain greater than two inches.\n",
    "But what if we want to know about all days with rain less than four inches and greater than one inch?\n",
    "This is accomplished through Python's *bitwise logic operators*, ``&``, ``|``, ``^``, and ``~``.\n",
    "Like with the standard arithmetic operators, NumPy overloads these as ufuncs which work element-wise on (usually Boolean) arrays.\n",
    "\n",
    "我们已经学习到了如何计算雨量小于4英寸的天数或者雨量大于2英寸的天数。但是如果我们期望的结果是雨量小于4英寸并且大于1英寸的天数，该怎么做？这可以通过Python的*位运算符*来实现，包括`&`、`|`、`^`和`~`。就像普通的算术运算符一样，NumPy重载了这些符号作为ufuncs，可以在数组（通常是布尔数组）每个元素值上进行位操作。\n",
    "\n",
    "> For example, we can address this sort of compound question as follows:\n",
    "\n",
    "例如，我们可以进行下面这个复合运算操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "29"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sum((inches > 0.5) & (inches < 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> So we see that there are 29 days with rainfall between 0.5 and 1.0 inches.\n",
    "\n",
    "从结果我们得出结论，雨量介于0.5和1.0英寸之间的天数是29天。\n",
    "\n",
    "> Note that the parentheses here are important–because of operator precedence rules, with parentheses removed this expression would be evaluated as follows, which results in an error:\n",
    "\n",
    "注意上面例子中两个比较运算的括号是必不可少的，因为运算符顺序规定，位运算优于比较运算，因此，如果省略括号，我们会得到下面语句一样的结果，显然是错误的：\n",
    "\n",
    "``` python\n",
    "inches > (0.5 & inches) < 1\n",
    "```\n",
    "\n",
    "> Using the equivalence of *A AND B* and *NOT (NOT A OR NOT B)* (which you may remember if you've taken an introductory logic course), we can compute the same result in a different manner:\n",
    "\n",
    "下面的例子使用了一种等同的语法来得到相同的结果，这种写法基于逻辑算术的基本知识：*A 且 B* 和 *非(非A 或 非B)*是相等的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "29"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sum(~( (inches <= 0.5) | (inches >= 1) ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Combining comparison operators and Boolean operators on arrays can lead to a wide range of efficient logical operations.\n",
    "\n",
    "结合比较运算和布尔运算就可以获得在数组上进行绝大部分逻辑运算的能力。\n",
    "\n",
    "> The following table summarizes the bitwise Boolean operators and their equivalent ufuncs:\n",
    "\n",
    "下表列出了布尔运算符及其对应ufuncs："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| 运算符\t    | 相应的ufunc    || 运算符\t    | 相应的ufunc    |\n",
    "|---------------|---------------------||---------------|---------------------|\n",
    "|``&``          |``np.bitwise_and``   ||&#124;      |``np.bitwise_or``    |\n",
    "|``^``          |``np.bitwise_xor``   ||``~``          |``np.bitwise_not``   |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Using these tools, we might start to answer the types of questions we have about our weather data.\n",
    "Here are some examples of results we can compute when combining masking with aggregations:\n",
    "\n",
    "使用这些工具，我们可以回头来解答前面例子中关于雨量的四个问题。下面的代码就是我们结合遮盖和聚合之后得到的问题的答案："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "无雨的天数             ： 215\n",
      "有雨的天数             ： 150\n",
      "雨量大于0.5英寸的天数   ： 37\n",
      "雨量小于0.2英寸的有雨天数： 75\n"
     ]
    }
   ],
   "source": [
    "print(\"无雨的天数             ：\", np.sum(inches == 0))\n",
    "print(\"有雨的天数             ：\", np.sum(inches != 0))\n",
    "print(\"雨量大于0.5英寸的天数   ：\", np.sum(inches > 0.5))\n",
    "print(\"雨量小于0.2英寸的有雨天数：\", np.sum((inches > 0) & (inches < 0.2)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Boolean Arrays as Masks\n",
    "\n",
    "## 使用布尔数组作为遮盖\n",
    "\n",
    "> In the preceding section we looked at aggregates computed directly on Boolean arrays.\n",
    "A more powerful pattern is to use Boolean arrays as masks, to select particular subsets of the data themselves.\n",
    "Returning to our ``x`` array from before, suppose we want an array of all values in the array that are less than, say, 5:\n",
    "\n",
    "在刚才的例子中，我们在布尔数组上应用聚合操作，得到结果。一个更加有用的场景是使用布尔数组作为遮盖，用来从数据集中选择目标数据出来。回到前面数组`x`的例子，如果我们要选择数组中所有小于5的元素，可以这样做："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5, 0, 3, 3],\n",
       "       [7, 9, 3, 5],\n",
       "       [2, 4, 7, 6]])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> We can obtain a Boolean array for this condition easily, as we've already seen:\n",
    "\n",
    "使用下面的比较运算很容易得到一个布尔数组，指代每个元素是否小于5："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[False,  True,  True,  True],\n",
       "       [False, False,  True, False],\n",
       "       [ True,  True, False, False]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x < 5"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Now to *select* these values from the array, we can simply index on this Boolean array; this is known as a *masking* operation:\n",
    "\n",
    "下面我们来从数组中*选择*符合条件的值出来，我们可以将上面得到的布尔数组作为索引带入数组中，成为*遮盖*操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 3, 3, 3, 2, 4])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[x < 5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> What is returned is a one-dimensional array filled with all the values that meet this condition; in other words, all the values in positions at which the mask array is ``True``.\n",
    "\n",
    "返回的是一个一维数组，里面的每个元素都满足条件：那就是结果数组中出现的元素对应的是遮盖布尔数组相应位置上为`True`真值。\n",
    "\n",
    "> We are then free to operate on these values as we wish.\n",
    "For example, we can compute some relevant statistics on our Seattle rain data:\n",
    "\n",
    "然后就可以灵活应用遮盖方法来获得我们需要的值了。例如，下面例子计算了很多西雅图雨量数据集相关的统计值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2014年下雨天雨量中位数（英寸）： 0.19488188976377951\n",
      "2014年夏天雨量中位数（英寸）： 0.0\n",
      "2014年夏天雨量最大值（英寸）： 0.8503937007874016\n",
      "除夏季外其他下雨天雨量中位数（英寸）： 0.20078740157480315\n"
     ]
    }
   ],
   "source": [
    "# 下雨天的遮盖数组\n",
    "rainy = (inches > 0)\n",
    "\n",
    "# 夏天的遮盖数组(6月21日是一年的第172天)\n",
    "days = np.arange(365)\n",
    "summer = (days > 172) & (days < 262)\n",
    "\n",
    "print(\"2014年下雨天雨量中位数（英寸）：\", np.median(inches[rainy]))\n",
    "print(\"2014年夏天雨量中位数（英寸）：\", np.median(inches[summer]))\n",
    "print(\"2014年夏天雨量最大值（英寸）：\",np.max(inches[summer]))\n",
    "print(\"除夏季外其他下雨天雨量中位数（英寸）：\", np.median(inches[rainy & ~summer]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> By combining Boolean operations, masking operations, and aggregates, we can very quickly answer these sorts of questions for our dataset.\n",
    "\n",
    "结合布尔操作、遮盖操作和聚合操作，我们可以很快在数据集中得到这类问题的答案。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Aside: Using the Keywords and/or Versus the Operators &/|\n",
    "\n",
    "## 附加内容：对比使用and/or关键字和&/|运算符\n",
    "\n",
    "> One common point of confusion is the difference between the keywords ``and`` and ``or`` on one hand, and the operators ``&`` and ``|`` on the other hand.\n",
    "When would you use one versus the other?\n",
    "\n",
    "使用关键字`and`和`or`，与使用运算符`&`和`|`，两者的区别，常常会困惑很多人。什么情况下你应该用哪种运算呢？\n",
    "\n",
    "> The difference is this: ``and`` and ``or`` gauge the truth or falsehood of *entire object*, while ``&`` and ``|`` refer to *bits within each object*.\n",
    "\n",
    "区别在于：`and`和`or`用在将*整个对象*当成真值或假值进行运算的场合，而`&`和`|`会针对*每个对象内的二进制位*进行运算。\n",
    "\n",
    "> When you use ``and`` or ``or``, it's equivalent to asking Python to treat the object as a single Boolean entity.\n",
    "In Python, all nonzero integers will evaluate as True. Thus:\n",
    "\n",
    "当你使用`and`或`or`的时候，相当于要求Python将对象当成是一个布尔值的整体。在Python中，所有的非0值都会被演算成True，因此："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bool(42), bool(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bool(42 and 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bool(42 or 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> When you use ``&`` and ``|`` on integers, the expression operates on the bits of the element, applying the *and* or the *or* to the individual bits making up the number:\n",
    "\n",
    "当你在整数上使用`&`和`|`运算时，这两个操作会运算整数中的每个二进制位，在每个二进制位上执行*二进制与*或*二进制或*操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b101010'"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bin(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b111011'"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bin(59)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b101010'"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bin(42 & 59)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'0b111011'"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bin(42 | 59)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Notice that the corresponding bits of the binary representation are compared in order to yield the result.\n",
    "\n",
    "对比一下上面例子中的结果是如何从操作数上进行二进制运算获得的。\n",
    "\n",
    "> When you have an array of Boolean values in NumPy, this can be thought of as a string of bits where ``1 = True`` and ``0 = False``, and the result of ``&`` and ``|`` operates similarly to above:\n",
    "\n",
    "当数组是一个NumPy的布尔数组时，你可以将这个布尔数组想象成它是由一系列二进制位组成的，因为``1 = True``和``0 = False``，所以使用`&`和`|`运算得到的结果类似上面的例子："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True,  True,  True, False,  True,  True])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.array([1, 0, 1, 0, 1, 0], dtype=bool)\n",
    "B = np.array([1, 1, 1, 0, 1, 1], dtype=bool)\n",
    "A | B"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Using ``or`` on these arrays will try to evaluate the truth or falsehood of the entire array object, which is not a well-defined value:\n",
    "\n",
    "在数组间使用`or`操作时，等同于要求Python把数组当成一个整体来求出最终的真值或假值，这样的值是不存在的，因此会导致一个错误："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-40-ea2c97d9d9ee>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mA\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mB\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"
     ]
    }
   ],
   "source": [
    "A or B"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Similarly, when doing a Boolean expression on a given array, you should use ``|`` or ``&`` rather than ``or`` or ``and``:\n",
    "\n",
    "类似的，当对于给定的数组进行布尔表达式运算时，你应该使用`|`或`&`，而不是`or`或`and`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, False, False,  True,  True,  True, False,\n",
       "       False])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = np.arange(10)\n",
    "(x > 4) & (x < 8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Trying to evaluate the truth or falsehood of the entire array will give the same ``ValueError`` we saw previously:\n",
    "\n",
    "同样如果试图把数组当成一个整体计算最终真值或假值也是不被允许的，结果还是我们前面看到的那个`ValueError`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-42-eecf1fdd5fb4>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m8\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"
     ]
    }
   ],
   "source": [
    "(x > 4) and (x < 8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> So remember this: ``and`` and ``or`` perform a single Boolean evaluation on an entire object, while ``&`` and ``|`` perform multiple Boolean evaluations on the content (the individual bits or bytes) of an object.\n",
    "For Boolean NumPy arrays, the latter is nearly always the desired operation.\n",
    "\n",
    "因此，你只需要记住：`and`和`or`对整个对象进行单个布尔操作，而`&`和`|`会对一个对象进行多个布尔操作（比如其中每个二进制位）。对于NumPy布尔数组来说，需要的总是后两者。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<!--NAVIGATION-->\n",
    "< [在数组上计算：广播](02.05-Computation-on-arrays-broadcasting.ipynb) | [目录](Index.ipynb) | [高级索引](02.07-Fancy-Indexing.ipynb) >\n",
    "\n",
    "<a href=\"https://colab.research.google.com/github/wangyingsm/Python-Data-Science-Handbook/blob/master/notebooks/02.06-Boolean-Arrays-and-Masks.ipynb\"><img align=\"left\" src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open in Colab\" title=\"Open and Execute in Google Colaboratory\"></a>\n"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
